

import CameraEnum from "../enum/camera_enum";
import Connection from "../net/connection/connection";
import { Config } from "../types/config_type";
import { consoleLog } from "../utils/console_log";


/**
 * 媒体流
 */
class VideoMediaStram {
  private _tempLocalStram: MediaStream | null = null;
  private _config: Config | null = null;
  private _currentNavigatormediaDevices: MediaDevices = navigator.mediaDevices
  private _mountDomTemp: string = ''
  private _isCurrentCameraType: CameraEnum = CameraEnum.front;
  private _isCurrentAudioType: boolean = true;
  private _connectionInstance: Connection = new Connection()

  constructor (config: Config) {
    this._config = config

    if (typeof this._config.audio == 'boolean') {
      this._isCurrentAudioType = this._config.audio
    }
  }

  /**
   * 创建临时媒体流
   * @param mountDom 挂载节点，能够被[querySelector] 获取到的节点
   * @returns 媒体流信息
   */
  async createTempMediaStream (mountDom: string, isUpdate: number = 0) :Promise<MediaStream> {
    this._mountDomTemp = mountDom

    let videoConfig = this._config?.video
    let audioConfig = this._config?.audio

    if (typeof videoConfig != 'boolean' || (typeof videoConfig == 'boolean' && videoConfig)) {
      if (typeof videoConfig != 'boolean') {
          videoConfig = {
            ...videoConfig,
            facingMode: this._isCurrentCameraType == CameraEnum.front ? 'user' : 'environment',
          }
      } else {
        videoConfig = {
          facingMode: this._isCurrentCameraType == CameraEnum.front ? 'user' : 'environment',
        }
      }
    }

    if (typeof audioConfig == 'boolean'){
      audioConfig = this._isCurrentAudioType
    }

    this._tempLocalStram = await this._currentNavigatormediaDevices.getUserMedia({
      audio: audioConfig,
      video: videoConfig,
      peerIdentity: this._config?.peerIdentity,
      preferCurrentTab: this._config?.preferCurrentTab,
    })

    if (isUpdate == 1) {
      this.publish()
    }

    this._mountRender(mountDom)

    return this._tempLocalStram
  }

  /**
   * 开始挂载渲染
   * @param mountDom 挂载节点，能够被[querySelector] 获取到的节点
   */
  private async _mountRender (mountDom: string) {
    const result = document.querySelector(mountDom) as HTMLElement

    const videoResult = result?.querySelector('#sf-rtc-local-video')

    if (videoResult) {
      result?.removeChild(videoResult)
    }

    // TODO
    const videoTag = document.createElement('video')
    videoTag.autoplay = true
    videoTag.playsInline = true
    videoTag.muted = true
    videoTag.id = 'sf-rtc-local-video'
    videoTag.style.width = result.style.width
    videoTag.style.height = result.style.height

    result?.append(videoTag)

    this._startPlayLocalStream()
  }

  /**
   * 播放本地媒体流
   */
  _startPlayLocalStream () {
    const result = document.querySelector('#sf-rtc-local-video') as HTMLVideoElement

    result.srcObject = this._tempLocalStram
  }

  /**
   * 切换相机
   */
  async switchCamera (type: CameraEnum) :Promise<void> {
    this._isCurrentCameraType = type
    
    this.createTempMediaStream(this._mountDomTemp, 1)
  }

  /**
   * 切换音源采集状态
   * @param status true 为采集；false 为不采集
   */
  async setMicroState (status: boolean):Promise<void> {
    this._isCurrentAudioType = status
    
    this.createTempMediaStream(this._mountDomTemp, 1)
  }

  /**
   * 发布当前流信息
   */
  async publish ():Promise<void> {
    if (this._tempLocalStram) {
      this._connectionInstance.addTrack(this._tempLocalStram?.getTracks(), this._tempLocalStram)
      
      return
    }
    
    consoleLog('error', this._config?.debugMode, 'Failed to create streaming media')
  }

  /**
   * 暂停发布当前流信息
   */
  stopPublish() {
    if (this._tempLocalStram) {
        this._tempLocalStram?.clone()
        this._connectionInstance.stopTranscribe()
      return
    }
    
    consoleLog('error', this._config?.debugMode, 'Failed to create streaming media')
  }


}


export default VideoMediaStram